package cn.edu.nyist.controller;

import cn.edu.nyist.entity.CommonUser;
import cn.edu.nyist.service.CommonUserService;
import cn.edu.nyist.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * (CommonUser)表控制层
 *
 * @author makejava
 * @since 2021-03-21 17:38:25
 */
@Controller
@RequestMapping("commonUser")
public class CommonUserController {


    private static Logger log = LoggerFactory.getLogger(CommonUserController.class);

    @Autowired
    private AjaxResult ajaxResult;

    @Autowired
    private CommonUserService commonUserService;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JavaMailSender javaMailSender;

    //操作redis
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Value("${mail.fromMail.sender}")
    private String sender;// 发送者



    /**
     * 跳转普通用户页面
     * @return
     */
    @GetMapping("/user")
    public String user(){
        return "yju/commonUser/userList";
    }

    @RequestMapping("/sendEmailCode")
    @ResponseBody
    public Object sendEmailCode(String email){
        log.info("sender:"+sender);
        log.info("email:"+email);

        CommonUser user = commonUserService.selectByEmail(email);
        if(user!=null){
            ajaxResult.ajaxFalse("该邮箱已注册！");
            return ajaxResult;
        }

        //发送次数限制 emailSendLimit
        if(redisTemplate.opsForValue().get(email+"SendLimit") !=null){
            ajaxResult.ajaxFalse("一分钟内仅可获取一次，请不要重复点击");
            return ajaxResult ;
        }

        SimpleMailMessage message = new SimpleMailMessage();
        //随机数生成6位验证码
        String code = VerifyCodeUtil.verifyCode(6);
        message.setFrom(sender);
        message.setTo(email);
        message.setSubject("宜居房屋租赁");// 标题
        message.setText("【宜居房屋租赁】你的动态码为："+code+"，有效时间为5分钟(若不是本人操作，可忽略该条邮件)");// 内容

        try {
            javaMailSender.send(message);
            log.info("文本邮件发送成功！");
            ajaxResult.ajaxTrue("文本邮件发送成功！");
            //发送限制
            redisTemplate.opsForValue().set(email+"SendLimit",code,60,TimeUnit.SECONDS);
            //在redis 中缓存，设置时间为五分钟300秒
            redisTemplate.opsForValue().set(email,code,300, TimeUnit.SECONDS);
        }catch  (MailSendException e){
            log.error("目标邮箱不存在");
            ajaxResult.ajaxFalse("目标邮箱不存在！");

        } catch (Exception e) {
            log.error("文本邮件发送异常！", e);
            ajaxResult.ajaxFalse("文本邮件发送异常！");
        }

        return ajaxResult;
    }

    //邮箱验证
    @RequestMapping("/sendEmailCodeCheck")
    @ResponseBody
    public Object sendEmailCodeCheck(String email){

        log.info("sender:"+sender);
        log.info("email:"+email);

        CommonUser user = commonUserService.selectByEmail(email);
        if(user==null){
            ajaxResult.ajaxFalse("该邮箱未注册！");
            return ajaxResult;
        }

        //发送次数限制 emailSendLimit
        if(redisTemplate.opsForValue().get(email+"CheckSendLimit") !=null){
            ajaxResult.ajaxFalse("一分钟内仅可获取一次，请不要重复点击");
            return ajaxResult ;
        }

        SimpleMailMessage message = new SimpleMailMessage();
        //随机数生成6位验证码
        String code = VerifyCodeUtil.verifyCode(6);
        message.setFrom(sender);
        message.setTo(email);
        message.setSubject("宜居房屋租赁-密码找回");// 标题
        message.setText("【宜居房屋租赁】 邮箱验证，你的动态码为："+code+"，有效时间为5分钟(若不是本人操作，可忽略该条邮件)");// 内容

        try {
            javaMailSender.send(message);
            log.info("文本邮件发送成功！");
            ajaxResult.ajaxTrue("文本邮件发送成功！");
            //发送限制
            redisTemplate.opsForValue().set(email+"CheckSendLimit",code,60,TimeUnit.SECONDS);
            //在redis 中缓存，设置时间为五分钟300秒
            redisTemplate.opsForValue().set(email+"Check",code,300, TimeUnit.SECONDS);
        }catch  (MailSendException e){
            log.error("目标邮箱不存在");
            ajaxResult.ajaxFalse("目标邮箱不存在！");

        } catch (Exception e) {
            log.error("文本邮件发送异常！", e);
            ajaxResult.ajaxFalse("文本邮件发送异常！");
        }

        return ajaxResult;
    }

    @RequestMapping("/emailCheck")
    @ResponseBody
    public Object emailCheck(String email,String validcode ){
        log.info("email:"+email);
        log.info("validcode:"+validcode);

        CommonUser user = commonUserService.selectByEmail(email);
        if(user==null){
            ajaxResult.ajaxFalse("该邮箱未注册！");
            return ajaxResult;
        }
        if(StringUtils.isEmpty(validcode)){
            ajaxResult.ajaxFalse("请输入动态码！");
            return ajaxResult;
        }

        String code = redisTemplate.opsForValue().get(email+"Check");
        log.info("code:"+code);
        if (code == null || "".equals(code)){
            ajaxResult.ajaxFalse("动态码已失效，请重新获取！");
            return ajaxResult;
        }

        if(validcode.equals(code)){

            ajaxResult.ajaxTrue("验证成功！");
            redisTemplate.delete(email+"Check");
            redisTemplate.delete(email+"CheckSendLimit");
        }  else  {
            ajaxResult.ajaxFalse("动态码错误！");
        }

        return ajaxResult;
    }



    /**
     * 表单提交登录
     * @param email
     * @param password
     * @param rememberMe
     * @param session
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public AjaxResult doLogin(String email,String password ,String rememberMe,
                              HttpSession session,HttpServletRequest request,HttpServletResponse response){

        if(StringUtils.isEmpty(email)){
            ajaxResult.ajaxFalse("邮箱不能为空！");
            return ajaxResult;
        }
        if(StringUtils.isEmpty(password)){
            ajaxResult.ajaxFalse("密码不能为空！");
            return ajaxResult;
        }
        try {
            CommonUser user = commonUserService.selectByEmail(email);
            if(StringUtils.isEmpty(user)){
                ajaxResult.ajaxFalse("该邮箱未注册！");
                return ajaxResult;
            }else{
                boolean matches = passwordEncoder.matches(password, user.getPassword());
                if(!matches){
                    ajaxResult.ajaxFalse("密码错误!");
                    return ajaxResult;
                }else{
                    session.setAttribute(Const.COMMONUSER,user);
                    ajaxResult.ajaxTrue("登录成功!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            ajaxResult.ajaxFalse("系统错误,请刷新");
        }
        return ajaxResult;
    }

    /**
     * 注册
     */
    @RequestMapping("/registerUser")
    @ResponseBody
    public Object registerUser(CommonUser commonUser ,String validcode){
        if(StringUtils.isEmpty(commonUser.getEmail())){
            ajaxResult.ajaxFalse("请输入邮箱！");
            return ajaxResult;
        }
        if(StringUtils.isEmpty(commonUser.getUsername())){
            ajaxResult.ajaxFalse("请输入昵称！");
            return ajaxResult;
        }
        if(StringUtils.isEmpty(commonUser.getPassword())){
            ajaxResult.ajaxFalse("请输入密码！");
            return ajaxResult;
        }
        if(StringUtils.isEmpty(validcode)){
            ajaxResult.ajaxFalse("请输入动态码！");
            return ajaxResult;
        }
        CommonUser user = commonUserService.selectByEmail(commonUser.getEmail());
        if(user!=null){
            ajaxResult.ajaxFalse("该邮箱已注册！");
            return ajaxResult;
        }
        String code = redisTemplate.opsForValue().get(commonUser.getEmail());
        if (StringUtils.isEmpty(code)){
            ajaxResult.ajaxFalse("动态码已失效，请重新获取！");
            return ajaxResult;
        }
        if(validcode.equals(code)){
            String stringDate = DateUtil.getStringDate("yyyy-MM-dd");
            commonUser.setCreatetime(stringDate);
            String encodePassword = passwordEncoder.encode(commonUser.getPassword());
            commonUser.setPassword(encodePassword);
            int count = commonUserService.insertCommonUser(commonUser);
            if(count>=0) {
                ajaxResult.ajaxTrue("注册成功！");
                redisTemplate.delete(commonUser.getEmail());
                redisTemplate.delete(commonUser.getEmail()+"SendLimit");
            }
        }else{
            ajaxResult.ajaxFalse("动态码输入有误！");
            return ajaxResult;
        }
        return ajaxResult;
    }

    @RequestMapping("/resetPassword")
    @ResponseBody
    public Object resetPassword(String password,String email){

        CommonUser commonUser = commonUserService.selectByEmail(email);
        if (commonUser == null) {
            ajaxResult.ajaxFalse("该邮箱未注册！");
            return ajaxResult;
        }

        if (password == null) {
            ajaxResult.ajaxFalse("请输入密码！");
            return ajaxResult;
        }

        String encodePassword = passwordEncoder.encode(password);
        commonUser.setPassword(encodePassword);

        log.info("commonUser:"+commonUser);

        int i = commonUserService.editByCommonUser(commonUser);
        if (i>=0){
            ajaxResult.ajaxTrue("密码重置成功！");
        }else{
            ajaxResult.ajaxFalse("密码重置失败！");
        }

        return  ajaxResult;
    }



    /**
     * 异步加载普通用户列表
     * @param pageno
     * @param pagesize
     * @param username
     * @param email
     * @return
     */
    @RequestMapping("/userList")
    @ResponseBody
    public Object userList(@RequestParam(value = "page", defaultValue = "1") Integer pageno,
                            @RequestParam(value = "limit", defaultValue = "5") Integer pagesize,
                            String username,String email){

        Map<String,Object> paramMap = new HashMap();
        paramMap.put("pageno",pageno);
        paramMap.put("pagesize",pagesize);

        //判断是否为空
        if(!StringUtils.isEmpty(username)) {
            paramMap.put("username",username);
        }

        if(!StringUtils.isEmpty(email)){
            paramMap.put("email",email);
        }
        PageBean<CommonUser> pageBean = commonUserService.queryPage(paramMap);
        Map<String,Object> rest = new HashMap();
        rest.put("code", 0);
        rest.put("msg", "");
        rest.put("count",pageBean.getTotalsize());
        rest.put("data", pageBean.getDatas());
        return rest;
    }

    /**
     * 跳转添加普通用户页面
     * @return
     */
    @GetMapping("/addUser")
    public String addUser(String type, Integer id, Model model){
        if(type != null && type.equals("edit")){
            CommonUser  commonUser = commonUserService.selectById(id);
            model.addAttribute(Const.COMMONUSER,commonUser);
        }
        return "yju/commonUser/addUser";
    }

    /**
     * 添加用户  修改用户
     * @param commonUser
     * @return
     */
    @PostMapping("/addUser")
    @ResponseBody
    public AjaxResult submitAddUser(CommonUser commonUser){
        CommonUser byEmail = commonUserService.selectByEmail(commonUser.getEmail());

        log.info("commonUser:"+commonUser);
        //on 表示通过 null 表示待审核
        if(commonUser.getId() !=null){
            CommonUser byId = commonUserService.selectById(commonUser.getId());

            if(byEmail != null && !byEmail.getId().equals(commonUser.getId())){
                //与修改邮箱一样，但存在数据库中，表示后来改的邮箱已存在
                ajaxResult.ajaxFalse("邮箱已存在");
                return ajaxResult;
            }

            //不等于空，且不相等
            if(!StringUtils.isEmpty(commonUser.getPassword()) && !byId.getPassword().equals(commonUser.getPassword())){
                log.info("原密码："+ byId.getPassword());
                String encodePassword = passwordEncoder.encode(commonUser.getPassword());
                log.info("新密码："+encodePassword);
                commonUser.setPassword(encodePassword);
            }
            int count = commonUserService.editByCommonUser(commonUser);
            if(count > 0){
                ajaxResult.ajaxTrue("修改成功");
            }else{
                ajaxResult.ajaxFalse("修改失败");
            }
        }else{

            if(byEmail != null){
                //邮箱存在数据库中
                ajaxResult.ajaxFalse("邮箱已存在");
                return ajaxResult;
            }

            String stringDate = DateUtil.getStringDate("yyyy-MM-dd");
            commonUser.setCreatetime(stringDate);
            // 设置密码
            if(!StringUtils.isEmpty(commonUser.getPassword())){
//                String md5Password = DigestUtils.md5DigestAsHex(
//                commonUser.getPassword().getBytes());
                String encodePassword = passwordEncoder.encode(commonUser.getPassword());
                log.info("密码："+encodePassword);
                commonUser.setPassword(encodePassword);
            }else{ //如果为空则设置默认邮箱为默认密码
//                String md5Password = DigestUtils.md5DigestAsHex(
//                                commonUser.getEmail().getBytes());
                String encodePassword = passwordEncoder.encode(commonUser.getEmail());
                log.info("密码："+encodePassword);
                commonUser.setPassword(encodePassword);
            }
            int count = commonUserService.insertCommonUser(commonUser);
            if(count > 0){
                ajaxResult.ajaxTrue("添加成功");
            }else{
                ajaxResult.ajaxFalse("添加失败");
            }
        }
        return ajaxResult;
    }

    @RequestMapping("/updateUsername")
    @ResponseBody
    public Object updateUsername(CommonUser commonUser,HttpSession session){
        log.info("commonUser:"+commonUser);

        if(StringUtils.isEmpty(commonUser.getEmail())){
            ajaxResult.ajaxFalse("邮箱为空，无法修改！");
            return ajaxResult;
        }

        if(StringUtils.isEmpty(commonUser.getUsername())){
            ajaxResult.ajaxFalse("请输入昵称！");
            return ajaxResult;
        }


        int count = commonUserService.editByCommonUser(commonUser);
        if(count > 0){
            ajaxResult.ajaxTrue("昵称修改成功！");
            CommonUser user = commonUserService.selectById(commonUser.getId());
            session.setAttribute(Const.COMMONUSER,user);
        }else{
            ajaxResult.ajaxFalse("昵称修改失败！");
        }
        return ajaxResult;

    }

    @RequestMapping("updatePassword")
    @ResponseBody
    public Object updatePassword(CommonUser commonUser,String newPassword,HttpSession session){
        CommonUser user = commonUserService.selectById(commonUser.getId());
        boolean matches = passwordEncoder.matches(commonUser.getPassword(), user.getPassword());
        //如果相等话，那么重置密码
        if(matches){
            //新密码，先进行编码
            String encodePassword = passwordEncoder.encode(newPassword);
            log.info("密码："+encodePassword);
            commonUser.setPassword(encodePassword);
        }else{
            ajaxResult.ajaxFalse("当前密码输入错误！");
            return ajaxResult;
        }

        int count = commonUserService.editByCommonUser(commonUser);
        if(count > 0){
            ajaxResult.ajaxTrue("密码修改成功！");
            //移除属性
            session.removeAttribute(Const.COMMONUSER);

        }else{
            ajaxResult.ajaxFalse("密码修改失败！");
        }
        return ajaxResult;
    }



    /**
     * 删除普通用户
     * @param data
     * @return
     */
    @PostMapping("/delUser")
    @ResponseBody
    public AjaxResult delUser(Data data){
        int count = commonUserService.delByCommonUserIds(data.getIds());
        if(count >= data.getIds().size()){
            ajaxResult.ajaxTrue("删除成功");
        }else{
            ajaxResult.ajaxFalse("删除失败");
        }
        return ajaxResult;
    }

    /**
     * 下载模板
     * @return
     */
    @RequestMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletRequest request, HttpServletResponse response){
        log.info("下载普通用户信息模板");
        String fileName="CommonUserTemplate.xlsx";
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("UTF-8");
        String userAgent = request.getHeader("User-Agent");

        FileInputStream inputStream=null;
        OutputStream os=null;
        try {
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else {
                // 非IE浏览器的处理：
                fileName = new String((fileName).getBytes("UTF-8"), "ISO-8859-1");
            }
            //获取文件的路径
            String filePath = getClass().getResource("/commonUserTemplate/" + fileName).getPath();
            filePath = URLDecoder.decode(filePath, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
            System.out.println("filePath:"+filePath);
            inputStream = new FileInputStream(filePath);
            os = response.getOutputStream();
            byte[] b=new byte[2048];
            int length;
            while ((length=inputStream.read(b))!=-1){
                os.write(b,0,length);
            }
            response.setHeader("Content-Length", String.valueOf(inputStream.getChannel().size()));
            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if(os!=null){
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }


    /**
    *跳转到 上传excel表的页面
     */
    @GetMapping("/bulkImport")
    public String bulkImport(){

        return "yju/commonUser/bulkImport";
    }

    //批量导入
    @PostMapping("/bulkImport")
    @ResponseBody
    public AjaxResult bulkImportStudent(@RequestParam(value="excel") MultipartFile file){
        log.info("=======普通用户信息=======");
        boolean record =false;
        //判断文件是否为空

        if(file == null){
            ajaxResult.ajaxFalse("文件是空!");
            return ajaxResult;
        }

        //获取文件名
        String name=file.getOriginalFilename();
        //进一步判断文件是否为空（即判断其大小是否为0或其名称是否为null）验证文件名是否合格
        long size=file.getSize();
        //文件类型检验
        ExcelUtils.validateExcel(name);
        if(name == null || StringUtils.isEmpty(name) && size == 0 && !ExcelUtils.validateExcel(name)) {
            ajaxResult.ajaxFalse("文件格式不正确！请使用.xls或.xlsx后缀文档。");
            return ajaxResult;
        }
        //创建处理Excel
        ReadExcel readExcel=new ReadExcel();
        //解析Excel，获取普通用户信息集合
        List<CommonUser> commonUserList = readExcel.getExcelInfo(file);
        if (commonUserList!=null && !commonUserList.toString().equals("[]") && commonUserList.size()>=1){
            record = true;
        }
        if( record ){
            //记录插入条数
            int count = 0;
            //变量普通信息
            for (CommonUser commonUser : commonUserList) {
                log.info("commonUser:" + commonUser);

                if (!StringUtils.isEmpty(commonUser.getUsername())
                        && !StringUtils.isEmpty(commonUser.getEmail())) {

                    CommonUser byEmail = commonUserService.selectByEmail(commonUser.getEmail());
                    //判断数据库中是否存在该email, 没有的话 则插入数据库中
                    if (byEmail == null ) {
                        //设置创建时间
                        String stringDate = DateUtil.getStringDate("yyyy-MM-dd");
                        commonUser.setCreatetime(stringDate);

                        //设置密码
                        String encodePassword = passwordEncoder.encode(commonUser.getEmail());
                        log.info("密码："+encodePassword);
                        commonUser.setPassword(encodePassword);
                        count += commonUserService.insertCommonUser(commonUser);
                    }

                }
            }
            if (count > 0) {
                ajaxResult.ajaxTrue("批量添加成功！");
            } else {
                ajaxResult.ajaxFalse("批量添加失败，请检查表内数据！");
            }
        }
        return ajaxResult;
    }

}